//: [Previous](@previous)
import Foundation
/*
 Swift的字符串类型String, 跟OC的NSString在API设计上还是有较大的差异
 */

import Foundation

// 创建 空字符串
var emptyStr1 = ""
var emptyStr2 = String()

//:## 字符串的拼接
var str: String = "1"
// 拼接
str.append("_2") //1_2
// 重置运算符 +
str = str + "_3" //1_2_3
// 重置运算符 +=
str += "_4" // 1_2_3_4
// \()插值
str = "\(str)_5" // 1_2_3_4_5
//长度
print(str.count) //9

// 检查前缀和后缀
print(str.hasPrefix("1_"))//true 前缀是1_开头
print(str.hasSuffix("_6"))//false 后缀不是_6结尾
//:## String的插入和删除
var str2 = "1_2"
//插入一个字符   startIndex:最开始的位置(1左边)  endIndex:最结尾的位置(2右边)
str2.insert("_", at: str2.endIndex) //1_2_
//插入字符串
str2.insert(contentsOf: "3_4", at: str2.endIndex) //"1_2_3_4"
//str.index: 索引   str2.index(after: str2.startIndex): 取出在str2.startIndex这个所以的后面的索引,现在第一个索引内容是1,after1就是1的后面
str2.insert(contentsOf: "993", at: str2.index(after: str2.startIndex)) //"1993_2_3_4"
str2.insert(contentsOf: "1", at: str2.index(before: str2.endIndex))//1993_2_3_14
// offset:偏移 (理解成向右偏移多少,负数就是往左偏移)  str.index(str2.startIndex, offsetBy: 5):从最左边位置开始右移动5个位置
str2.insert(contentsOf: "0", at: str.index(str2.startIndex, offsetBy: 5)) //1993_02_3_14
//删除 删除1那个位置
str2.remove(at: str2.firstIndex(of: "1")!)//993_02_3_14"
/*
 str.removewAll 遍历这个字符串的每一个字符,每一次都返回单一字符,然后你去判断这个字符要不要删,返回true就是删
 $0 == "9" : 是9 就都删
*/
str2.removeAll { $0 == "9" } //3_02_3_14
//删除一个范围
var range = str2.index(str2.endIndex, offsetBy: -4) ..< str2.index(before: str2.endIndex) //倒数第一个字符往左偏移4个位置 ..< 倒数第一个字符
print(str2)
str2.removeSubrange(range) //3_02_3_14 (少了3_1)
//:## Substring
/*
 String可以通过 下标 / prefix / suffix 等截取子串, 子串类型不是String, 而是Substring
 其实就是只要在String里面截取部分内容出来, 这部分内容的类型就是Substring
 但是其实Substring还是可以使用String的大部分方法(系统给Substring配套了类似String的API方法)
 
 Substring 和它的base, 共享字符串数据 (substring最初其实就是指向原始String里面的一段内容)
 Substring转为String时, 会重新分配新的内存存储字符串数据
 */
var str3 = "1_2_3_4_5"
var subStr1 = str3.prefix(3)//1_2  截取了前三
var subStr2 = str3.suffix(3)//4_5  截取了后三
var range1 = str3.startIndex ..< str3.index(str3.startIndex, offsetBy: 2)
var subStr3 = str3[range1]//1_ 截取01位置
print(subStr3.base) //1_2_3_4_5 Substring的特殊属性,base,指向这个Substring最初的String(相当于str3)
//⚠️ Substring -> String 可以新建一个对象来接受
var str4 = String(subStr3)
//:## String相关的协议
/*
 BidirectionalCollection 协议包含的部分内容👇🏻
 startIndex / endIndex属性 / index方法
 String 和 Array 都遵守了这个协议
 
 RangeReplaceableCollection 协议包含的部分内容👇🏻
 append / insert / remove 方法
 String 和 Array 都遵守了这个协议
 Dictionary / Set 也有实现上述协议中声明的一些方法, 只是没有遵守上述协议
 */
//: ## 多行String
/*
 3个"开头, 3个"结尾. 3个"开头的下面那行 和 3个"结尾上面那行 之间的内容就是多行String的内容
 1.里面的内容可以随便写双引号/单引号
 2.假如需要展示3个双引号在内容里面, \"\"\"
 3.缩进以结尾的3引号位对齐线
 */
let str5 = """
1
 "2"
  '4'
   5

6
"""
print(str5)
//:## String与Nsstring
/*
 String 与 NSString 之间可以随时随地桥接转换
 String(可变的)  NSString(不可变的)
 
 很多情况下会觉得String的API过于复杂难用, 可以考虑将String转为NSString去使用
 var str6: String = "Jack"
 var str7: NSString = "Rose"

 var str8 = str6 as NSString //String -> NSString
 var str9 = str7 as String //NSString -> String

 //oc NSString的直接range取值, 比Swift的String好用
 var str10 = str7.substring(with: NSRange(location: 0, length: 2)) //Ro
 
 //比较字符串内容是否等价
 String : 使用 == 运算符
 NSString : 使用isEqual方法, 也可以使用 == 运算符(本质其实也是调用isEqual)
 str6 == str9
 str7.isEqual(Str8) 
 */






















//: [Next](@next)
